﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ComparteTuTiempo.Models;
using ComparteTuTiempo.Models.BusquedaModelClass;
using ComparteTuTiempo.Models.CustomClass;
using ComparteTuTiempo.Models.CustomDetallesUsuario;
using System.IO;
using UploadBasico.Models;
using ComparteTuTiempo.Models.CustomEditarUsuario;
using ComparteTuTiempo.Models.CustomModels;

namespace ComparteTuTiempo.Controllers
{
    public class UsuariosController : Controller
    {
        private compartetutiempoEntities db = new compartetutiempoEntities();


        //
        // GET: /Usuarios/Busqueda

        public ActionResult Busqueda()
        {
            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre");
            ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");


            List<BusquedaModelClass> ls = new List<BusquedaModelClass>();
            BusquedaModelClass aux;//= new Models.BusquedaModelClass.BusquedaModelClass();
            foreach (var item in db.usuarios.Where(x => x.inactivo == 0).ToList())
            {
                aux = new BusquedaModelClass(item);
                ls.Add(aux);
            }

            return View(ls);
        }


        //
        // POST: /Usuarios/Busqueda

        [HttpPost]
        public ActionResult Busqueda(BusquedaModelClass usu)
        {

            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre");
            ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");

            //FEISIMO NO LO SIGUIENTE!!! PERO NO SE COMO INSTANCIAR LA VARIABLE USUARIO PARA PODER HACER EL TRATAMIENTO POSTERIORMENTE
            List<BusquedaModelClass> ls = new List<BusquedaModelClass>();
            BusquedaModelClass aux;// = new Models.BusquedaModelClass.BusquedaModelClass();


            if (usu.idProfesionSelcionada != 0 && usu.idProvinciaSelecionada != 0 && usu.nombreUsuarioBuscar != null)
            {
                var resultado = from itemA in db.usuarios
                                join itemB in db.profesionesusuarios on itemA.idUsuarios equals itemB.idUsuarios
                                where itemB.idProfesiones.Equals(usu.idProfesionSelcionada) &&
                                      itemA.provincias.idProvincias.Equals(usu.idProvinciaSelecionada) &&
                                      itemA.nombre.Contains(usu.nombreUsuarioBuscar) &&
                                      itemA.inactivo == 0

                                select itemA;

                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }


            }
            else if (usu.idProfesionSelcionada != 0 && usu.nombreUsuarioBuscar != null)
            {
                var resultado = from itemA in db.usuarios
                                join itemB in db.profesionesusuarios on itemA.idUsuarios equals itemB.idUsuarios
                                where itemB.idProfesiones.Equals(usu.idProfesionSelcionada) &&
                                      itemA.nombre.Contains(usu.nombreUsuarioBuscar) &&
                                      itemA.inactivo == 0

                                select itemA;

                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            else if (usu.idProvinciaSelecionada != 0 && usu.nombreUsuarioBuscar != null)
            {
                var resultado = from itemA in db.usuarios
                                where itemA.provincias.idProvincias.Equals(usu.idProvinciaSelecionada) &&
                                      itemA.nombre.Contains(usu.nombreUsuarioBuscar) &&
                                      itemA.inactivo == 0

                                select itemA;

                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            else if (usu.idProfesionSelcionada != 0 && usu.idProvinciaSelecionada != 0)
            {
                var resultado = from itemA in db.usuarios
                                join itemB in db.profesionesusuarios on itemA.idUsuarios equals itemB.idUsuarios
                                where itemB.idProfesiones.Equals(usu.idProfesionSelcionada) &&
                                      itemA.provincias.idProvincias.Equals(usu.idProvinciaSelecionada) &&
                                      itemA.inactivo == 0

                                select itemA;

                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            else if (usu.idProfesionSelcionada != 0)
            {
                var resultado = from itemA in db.usuarios
                                join itemB in db.profesionesusuarios on itemA.idUsuarios equals itemB.idUsuarios
                                where itemB.idProfesiones.Equals(usu.idProfesionSelcionada) &&
                                      itemA.inactivo == 0
                                select itemA;

                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            else if (usu.idProvinciaSelecionada != 0)
            {
                //var resultado = db.usuarios.Where(u => u.provincias.idProvincias.Equals(usu.idProvinciaSelecionada)).ToList();
                var resultado = from itemA in db.usuarios
                                where itemA.provincias.idProvincias.Equals(usu.idProvinciaSelecionada) &&
                                      itemA.inactivo == 0
                                select itemA;


                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            else if (usu.nombreUsuarioBuscar != null)
            {
                // var resultado = db.usuarios.Where(u => u.nombre.Contains(usu.nombreUsuarioBuscar)).ToList();
                var resultado = from itemA in db.usuarios
                                where itemA.nombre.Contains(usu.nombreUsuarioBuscar) &&
                                      itemA.inactivo == 0
                                select itemA;
                foreach (var item in resultado.ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            else
            {
                foreach (var item in db.usuarios.Where(x => x.inactivo == 0).ToList())
                {
                    aux = new BusquedaModelClass(item);
                    ls.Add(aux);
                }
            }
            if (Request.IsAjaxRequest())
            {
                return PartialView("_BusquedaPartial", ls);
            }
            return View(ls);

        }

        //
        // GET: /Usuarios/Details/5/

        public ActionResult Details(int id = 0)
        {

            //Si no existe la variable de session id nos devolverá directamente a la ventana de inicio!
            if (Session["id"] == null)
            {
                return RedirectToAction("Index", "Home");
            }

            CustomDetallesUsuario detalleUsuario = new CustomDetallesUsuario();
            detalleUsuario.trabajosSolicitados = new List<trabajossolicitados>();
            detalleUsuario.usuario = db.usuarios.Find(id);

            int trabajosRealizados = db.trabajossolicitados.Where(t => t.idtrabajador == id && t.realizado == true).Count();
            int? sumaPuntos = db.trabajossolicitados.Where(t => t.idtrabajador == id).Select(t => t.puntuacion).Sum();
            if (trabajosRealizados > 0)
            {
                long? puntuacionMedia = sumaPuntos / trabajosRealizados;
                detalleUsuario.usuario.numtrabajosrealizados = trabajosRealizados;
                detalleUsuario.usuario.puntos = puntuacionMedia;
            }
            db.SaveChanges();


            //Parte de la comboBox
            var p = (db.profesionesusuarios.Where(profesionesusuarios => profesionesusuarios.idUsuarios == id ))
                        .Select(s => new { s.idProfesiones, s.profesiones.nombre });

            ViewBag.profesiones = new SelectList(p, "idProfesiones", "nombre");
            //Fin Parte ComboBox

            foreach (var item in db.trabajossolicitados.Where(x => x.idtrabajador == id &&x.realizado==true).ToList())
                detalleUsuario.trabajosSolicitados.Add(item);

            if (detalleUsuario.usuario == null || Session["id"] == null)
            {
                return HttpNotFound();
            }


            return View(detalleUsuario);


        }

        [HttpPost]
        public ActionResult Details(CustomDetallesUsuario usu)
        {
            //Si no existe la variable de session id nos devolverá directamente a la ventana de inicio!
            if (Session["id"] == null)
            {
                return RedirectToAction("Index", "Home");
            }

            CustomDetallesUsuario detalleUsuario = new CustomDetallesUsuario();
            detalleUsuario.trabajosSolicitados = new List<trabajossolicitados>();
            detalleUsuario.usuario = db.usuarios.Find(usu.usuario.idUsuarios);

            //Parte de la comboBox
            var p = (db.profesionesusuarios.Where(profesionesusuarios => profesionesusuarios.idUsuarios == usu.usuario.idUsuarios))
                    .Select(s => new { s.idProfesiones, s.profesiones.nombre });

            ViewBag.profesiones = new SelectList(p, "idProfesiones", "nombre");
            //Fin de la comboBox

            if (usu.idProfesionSelcionada != 0)
            {
                var filtroProfesiones = from itemA in db.trabajossolicitados
                                        where itemA.idtrabajador == usu.usuario.idUsuarios && itemA.idProfesion == usu.idProfesionSelcionada && itemA.realizado == true
                                        select itemA;
                foreach (var item in filtroProfesiones.ToList())
                    detalleUsuario.trabajosSolicitados.Add(item);
            }
            else
            {
                foreach (var item in db.trabajossolicitados
                    .Where(x => x.idtrabajador == usu.usuario.idUsuarios 
                    && x.realizado==true )
                    .ToList())
                    detalleUsuario.trabajosSolicitados.Add(item);
            }

            if (detalleUsuario.usuario == null || Session["id"] == null)
            {
                return HttpNotFound();
            }

            return View(detalleUsuario);


        }



        //
        // GET: /Usuarios/Create

        public ActionResult Create()
        {
            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre");
            ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");
            return View();
        }

        //
        // POST: /Usuarios/Create

        [HttpPost]
        public ActionResult Create(CustomClass custom, string[] profes)
        {
            try
            {
                //Si los campos contraseñas coinciden, seguir grabando datos
                if (custom.pass == custom.passconf)
                {
                    // sha1
                    custom.usuario.password = Encode(custom.pass);
                    custom.usuario.horasDisponibles = new TimeSpan( 0,0,0);
                    try
                    {
                        if (custom.usuario.foto == null) custom.usuario.foto = "/FicherosSubidos/foto_persona.jpg";

                        db.usuarios.Add(custom.usuario);
                        db.SaveChanges();

                        //Comprobar si se ha marcado ninguna
                        if (custom.SelectedItemId != null)
                        {
                            foreach (var item in custom.SelectedItemId)
                            {
                                profesionesusuarios usupro = new profesionesusuarios();
                                usupro.idProfesiones = int.Parse(item);
                                custom.usuario.profesionesusuarios.Add(usupro);
                            }

                            db.SaveChanges();
                        }
                        //Si se guardaron los datos entonces cargamos la sessión al usuario
                        Session["nombre"] = custom.usuario.nombre + " " + custom.usuario.apellidos;
                        string auxEmail = custom.usuario.email;
                        Session["id"] = db.usuarios.Where(x => x.email.Equals(auxEmail)).FirstOrDefault().idUsuarios;//siempre nos devolvera uno


                    }
                    catch (Exception ex)
                    {
                        ex.ToString();
                    }

                    return RedirectToAction("Busqueda");
                }
                else
                {
                    //Volver a meterle los datos a la vista, si no... PETA
                    ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre");
                    ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");
                    //Mensaje de error
                    ViewBag.mensajePass = ("Las contraseñas no coinciden");
                    return View();
                }
            }
            catch (Exception ex)
            {
                ex.ToString();
            }

            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre", custom.usuario.provincia);
            return View(custom.usuario);
        }

        public ActionResult Edit(int id = 0)
        {
            //Si no existe la variable de session id nos devolverá directamente a la ventana de inicio!
            if (Session["id"] == null)
            {
                return RedirectToAction("Index", "Home");
            }

            CustomEditarUsuario aux = new CustomEditarUsuario();
            aux.SelectedItemId = Enumerable.Empty<string>();

            aux.usuario = db.usuarios.Find(id);
            if (aux.usuario == null)
            {
                return HttpNotFound();
            }

            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre", aux.usuario.provincia);
            ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");
            foreach (var item in aux.usuario.profesionesusuarios)
            {
                aux.SelectedItemId.Intersect(new[] { item.idProfesiones.ToString() });
            }

            Session["urlFoto"] = aux.usuario.foto;

            return View(aux);
        }

        //
        // POST: /Usuarios/Edit/5

        [HttpPost]
        public ActionResult Edit(CustomEditarUsuario usu)
        {
            //Si no existe la variable de session id nos devolverá directamente a la ventana de inicio!
            if (Session["id"] == null)
            {
                return RedirectToAction("Index", "Home");
            }


            if (ModelState.IsValid)
            {
                profesionesusuarios prousu;
                int idUsu = (int)Session["id"];

                //Borramos todas las profesiones 
                IEnumerable<profesionesusuarios> listaprofs = db.profesionesusuarios.Where(x => x.idUsuarios.Equals(idUsu)).ToList();
                foreach (var item in listaprofs)
                {
                    db.profesionesusuarios.Remove(item);
                }

                //Añadimos todas las profesiones selecionadas ! 
                foreach (var item in usu.SelectedItemId)
                {
                    if (item != "false")
                    {
                        prousu = new profesionesusuarios();
                        prousu.idProfesiones = int.Parse(item);
                        prousu.idUsuarios = idUsu;
                        db.profesionesusuarios.Add(prousu);
                    }
                    else
                    {
                        //Borrar Profesion
                    }
                }

                //Carga de datos predetirminados o si no estas especificado
                usu.usuario.idUsuarios = idUsu;


                db.Entry(usu.usuario).State = EntityState.Modified;
                db.SaveChanges();


                if (Session["urlFoto"] != null && usu.usuario.foto != (String)Session["urlFoto"])
                {
                    //Borramos la foto antigua
                    try
                    {
                        // Server.MapPath("/FicherosSubidos/") + usuarioFoto.foto.Replace("/FicherosSubidos/", string.Empty);
                        System.IO.File.Delete(Server.MapPath("/FicherosSubidos/") + ((String)Session["urlFoto"]).Replace("/FicherosSubidos/", string.Empty));
                    }
                    catch (System.IO.IOException e)
                    {
                        e.ToString();
                    }
                    Session.Remove("urlFoto");
                }


                return RedirectToAction("Busqueda");
            }

            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre", usu.usuario.provincia);
            ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");
            return View(usu);
        }


        public ActionResult DarBaja()
        {
            //int id = int.Parse(Session["id"]);
            usuarios usuario = db.usuarios.Find((int)Session["id"]);
            usuario.inactivo = 1;
            db.usuarios.Attach(usuario);

            db.Entry(usuario).State = EntityState.Modified;

            db.SaveChanges();
            return RedirectToAction("Busqueda");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        //
        // GET: /Usuarios/Login

        public ActionResult Login()
        {

            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre");
            return View();
        }

        //
        // POST: /Usuarios/Login

        [HttpPost]
        public ActionResult Login(CustomLogin usu)
        {

            if (ModelState.IsValid)
            {
                //sha1
                usu.pass = Encode(usu.pass);

                var query = db.usuarios.Where(u => u.email.Equals(usu.email) && u.password.Equals(usu.pass) && u.inactivo == 0);
                int cont = query.Count();

                if (cont != 0)
                {
                    usuarios usuario = new usuarios();
                    usuario = query.First();

                    //Almacena datos en sesion
                    Session["nombre"] = usuario.nombre + " " + usuario.apellidos;
                    Session["id"] = usuario.idUsuarios;

                    return RedirectToAction("Busqueda");
                }
                else
                {
                    ViewBag.LoginFail = "Usuario y/o Contraseña incorrectos.";
                }

            }

            return View();
        }

        // metodo de LOGEO para la ventana MODAL
        // Recive los parametros por post desde el formulario sin tipear porque no me deja tipear la pagina
        [HttpPost]
        public ActionResult LoginModal()
        {
            if (ModelState.IsValid)
            {
                string email = Request.Form["email"];
                string pass = Request.Form["pass"];

                //sha1
                pass = Encode(pass);

                var query = db.usuarios.Where(u => u.email.Equals(email) && u.password.Equals(pass));

                int cont = query.Count();

                if (cont != 0)
                {
                    usuarios usuario = new usuarios();
                    usuario = query.First();

                    //Almacena datos en sesion
                    Session["nombre"] = usuario.nombre + " " + usuario.apellidos;
                    Session["id"] = usuario.idUsuarios;

                    return RedirectToAction("Busqueda");
                }

            }
            //Si falla redirige a una página de login concreta para especificar que ocurre
            return View("Login");
        }

        public ActionResult cambiopass(CustomCambioPass passwords)
        {
            
            usuarios usu = db.usuarios.Find((int)Session["id"]);
            CustomEditarUsuario auxUsu = new CustomEditarUsuario();

            if (ModelState.IsValid)
            {

                passwords.passold = Encode(passwords.passold);
                if (usu.password.Equals(passwords.passold))
                {
                    if (passwords.pass.Equals(passwords.passconf))
                    {
                        usu.password = Encode(passwords.pass);
                        db.Entry(usu).State = EntityState.Modified;
                        db.SaveChanges();
                        ViewBag.Mensaje = "La contraseña ha sido cambiada";
                    }
                    else
                    {
                        //No coinciden las pass
                        ViewBag.MensajeError = "No coincidenron las contraseñas";
                    }
                }
                else
                {
                    //No coincide con la pass antigua
                    ViewBag.MensajeError = "No coincicide la contraseña antigua con la escrita";
                }
   
            }

            ViewBag.provincia = new SelectList(db.provincias.OrderBy(x => x.nombre), "idProvincias", "nombre", usu.provincia);
            ViewBag.profesiones = new SelectList(db.profesiones.OrderBy(x => x.nombre), "idProfesiones", "nombre");
            auxUsu.usuario = usu;

            return View("Edit", auxUsu);
        }

        public ActionResult Logoff()
        {
            Session.RemoveAll();
            return RedirectToAction("Index", "Home");
        }

        public static string Encode(string cadena)
        {
            var hash = System.Security.Cryptography.SHA1.Create();
            var encoder = new System.Text.ASCIIEncoding();
            var combined = encoder.GetBytes(cadena ?? "");
            return BitConverter.ToString(hash.ComputeHash(combined)).ToLower().Replace("-", "");
        }

        #region Upload Methods
        [HttpGet]
        public ActionResult Upload()
        {
            return View();
        }

        /// Guarda el fichero subido a la carpeta FicherosSubidos y devuelve un mensaje
        /// de vuelta al plugin de de jQuery uploadify
        /// </summary>
        /// <param name="fileData"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Upload(HttpPostedFileBase fileData)
        {
            string aux;
            FicheroSubido foto = new FicheroSubido();

            usuarios usuarioFoto = new usuarios();

            //if (Session["id"] != null)
            //    usuarioFoto = db.usuarios.Find((int)Session["id"]);

            try
            {
                aux = DateTime.Now.ToString("dd-MM-yy_hh-mm-ss_") + Path.GetFileName(fileData.FileName);
                foto.Path = Server.MapPath("/FicherosSubidos/") + aux;
                fileData.SaveAs(foto.Path);

                //Sobreescribimos la variable foto.Path
                foto.Path = "/FicherosSubidos/" + aux;



            }
            catch (Exception ex)
            {
                return Content("Error subiendo fichero: " + ex.Message);
            }
            return Content(foto.Path);
        }
        #endregion
    }
}